﻿using System;
using System.Windows;
using System.Windows.Media.Animation;
using System.Reflection;

namespace SBPweb.PROvibe.Client.Framework.Utilities.Animations
{

    public static class StoryboardHelper
    {
        public static void BeginElementStoryBoard(UIElement target, string storyBoardName, PropertyPath propertyPath)
        {
            BeginElementStoryBoard(target, storyBoardName, propertyPath, null);
        }

        public static void BeginElementStoryBoard(UIElement target, string storyBoardName, PropertyPath propertyPath, EventHandler completedHandler)
        {
            BeginElementStoryBoard(Application.Current.Resources, target, storyBoardName, propertyPath, completedHandler);
        }

        public static void BeginElementStoryBoard(UIElement target, string subTargetName, string storyBoardName, PropertyPath propertyPath)
        {
            BeginElementStoryBoard(target, subTargetName, storyBoardName, propertyPath, null);
        }

        public static void BeginElementStoryBoard(UIElement target, string subTargetName, string storyBoardName, PropertyPath propertyPath, EventHandler completedHandler)
        {
            BeginElementStoryBoard(Application.Current.Resources, target, subTargetName, storyBoardName, propertyPath, completedHandler);
        }

        public static void BeginElementStoryBoard(ResourceDictionary resources, UIElement target, string storyBoardName, PropertyPath propertyPath)
        {
            BeginElementStoryBoard(resources, target, storyBoardName, propertyPath, null);
        }

        public static void BeginElementStoryBoard(ResourceDictionary resources, UIElement target, string storyBoardName, PropertyPath propertyPath, EventHandler completedHandler)
        {
            BeginElementStoryBoard(resources, target, null, storyBoardName, propertyPath, completedHandler);
        }

        public static void BeginElementStoryBoard(ResourceDictionary resources, UIElement target, string subTargetName, string storyBoardName, PropertyPath propertyPath, EventHandler completedHandler)
        {
            if (!resources.Contains(storyBoardName))
            {
                throw new ArgumentException(string.Format("Resource with name {0} not found!", storyBoardName));
            }
            if (!string.IsNullOrEmpty(subTargetName))
            {
                target = (target as FrameworkElement).FindName(subTargetName) as UIElement;
            }
            Storyboard sbAlpha = resources[storyBoardName] as Storyboard;
            Storyboard sb = CloneStoryBoard(sbAlpha);
            Storyboard.SetTarget(sb, target);
            Storyboard.SetTargetProperty(sb, propertyPath);
            if(completedHandler != null)
            {
                sb.Completed += completedHandler;
            }
            sb.Begin();
        }

        public static T CloneTimeline<T>(T clonable)
            where T : Timeline
        {
            Type type = clonable.GetType();
            T clone = (T)Activator.CreateInstance(type);
            foreach (PropertyInfo pI in type.GetProperties(BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.Public))
            {
                if (pI.Name != "Children" && pI.CanWrite)
                {
                    pI.SetValue(clone, pI.GetValue(clonable, null), null);
                }
            }
            return clone;
        }

        public static Storyboard CloneStoryBoard(Storyboard clonable)
        {
            Storyboard clone = CloneTimeline<Storyboard>(clonable);
            foreach (Timeline tln in clonable.Children)
            {
                clone.Children.Add(CloneTimeline<Timeline>(tln));
            }
            return clone;
        }
    }

}